widget: Move frame clock handling to vfunc
authorBenjamin Otte <otte@redhat.com>
Wed, 11 Apr 2018 01:03:35 +0000 (03:03 +0200)
committerBenjamin Otte <otte@redhat.com>
Wed, 11 Apr 2018 01:16:34 +0000 (03:16 +0200)
Instead of connecting to / disconnecting from the frame clock, do it
inside the vfuncs next to changing the priv->realized boolean.

This removes a race between those 2 cases that could cause child
widgets' unrealize handlers to reconnect this widget to the frame clock
because it was still marked as realize when the widget had already
disconnected from the frame clock.

Fixes #168

gtk/gtkwidget.c

index a0955657bd5401201c13970372958807a23273f6..bf958a1be781e9e0a7952b136aa57275484c8e5a 100644 (file)
@@ -3689,14 +3689,16 @@ gtk_widget_has_tick_callback (GtkWidget *widget)
 }
 
 static void
-gtk_widget_connect_frame_clock (GtkWidget     *widget,
-                                GdkFrameClock *frame_clock)
+gtk_widget_connect_frame_clock (GtkWidget *widget)
 {
   GtkWidgetPrivate *priv = widget->priv;
+  GdkFrameClock *frame_clock;
 
   if (GTK_IS_CONTAINER (widget))
     gtk_container_start_idle_sizer (GTK_CONTAINER (widget));
 
+  frame_clock = gtk_widget_get_frame_clock (widget);
+
   if (priv->tick_callbacks != NULL && !priv->clock_tick_id)
     {
       priv->clock_tick_id = g_signal_connect (frame_clock, "update",
@@ -3712,8 +3714,7 @@ gtk_widget_connect_frame_clock (GtkWidget     *widget,
 }
 
 static void
-gtk_widget_disconnect_frame_clock (GtkWidget     *widget,
-                                   GdkFrameClock *frame_clock)
+gtk_widget_disconnect_frame_clock (GtkWidget *widget)
 {
   GtkWidgetPrivate *priv = widget->priv;
 
@@ -3724,6 +3725,10 @@ gtk_widget_disconnect_frame_clock (GtkWidget     *widget,
 
   if (priv->clock_tick_id)
     {
+      GdkFrameClock *frame_clock;
+
+      frame_clock = gtk_widget_get_frame_clock (widget);
+
       g_signal_handler_disconnect (frame_clock, priv->clock_tick_id);
       priv->clock_tick_id = 0;
       gdk_frame_clock_end_updating (frame_clock);
@@ -3798,8 +3803,6 @@ gtk_widget_realize (GtkWidget *widget)
 
       if (priv->context)
        gtk_style_context_set_scale (priv->context, gtk_widget_get_scale_factor (widget));
-      gtk_widget_connect_frame_clock (widget,
-                                      gtk_widget_get_frame_clock (widget));
 
       gtk_widget_pop_verify_invariants (widget);
     }
@@ -3829,9 +3832,6 @@ gtk_widget_unrealize (GtkWidget *widget)
       if (widget->priv->mapped)
         gtk_widget_unmap (widget);
 
-      gtk_widget_disconnect_frame_clock (widget,
-                                         gtk_widget_get_frame_clock (widget));
-
       g_signal_emit (widget, widget_signals[UNREALIZE], 0);
       g_assert (!widget->priv->mapped);
       g_assert (!widget->priv->realized);
@@ -8746,6 +8746,8 @@ gtk_widget_real_realize (GtkWidget *widget)
     }
 
   priv->realized = TRUE;
+
+  gtk_widget_connect_frame_clock (widget);
 }
 
 /*****************************************
@@ -8771,6 +8773,8 @@ gtk_widget_real_unrealize (GtkWidget *widget)
 
   gtk_widget_forall (widget, (GtkCallback)gtk_widget_unrealize, NULL);
 
+  gtk_widget_disconnect_frame_clock (widget);
+
   priv->realized = FALSE;
 
   if (_gtk_widget_get_has_surface (widget))